/*************************************************************************
	> File Name: protocolhandler.h
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2018年01月24日 星期三 17时08分13秒
 ************************************************************************/

#ifndef __PROTOCOLHANDLER_H__
#define __PROTOCOLHANDLER_H__

#include <stdio.h>
#include <utils/timer.h>
#include "../../transport.h"
#include "protocol.h"
#include <vector>
#include <map>
#include <time.h>

class ProtocolHandler:public RPCProtocol,public RPCTransportInterface,public TimerTask
{
public:

    enum
    {
        NONE = 0x0000,
        HAS_TOKEN = 0x0001,
        HAS_TIMER = 0x0002,
        SYNC_SEND = 0x0004,
        DO_ENCRYPT = 0x0008
    };

    //bool token = FALSE,
    //bool needtimer = true
    ProtocolHandler(U16  flag,
                    TransportInterface *interface = NULL);
    virtual ~ProtocolHandler();

    virtual void RunTimer();
    void StopTimer();

    void TimeOut();

    /*
     * 响应消息
     */
    virtual void OnResult(int msgId,Json::Value &result);
    virtual void OnRequest(int msgId,Json::Value &request);
    virtual DAS_RESULT OnRequest(int msgId,
                           const std::string &method,
                           const Json::Value &params, Json::Value &result);

    /*
     * jsonrpc
     */
    virtual S32 SendJsonRpc(
            tJsonRpcInterface _interface,
            const std::string &method,
            const Json::Value &params,
            int timeout = 30);

    virtual bool ReturnJsonRpc(
            S32 msgId,
            const std::string &method, const Json::Value &result);

    virtual BOOL SendAsyncJson(
            S32 msgId,
            tJsonRpcInterface _interface,
            const std::string &method,
            const Json::Value &params);

    virtual bool ReturnAsyncResult(
            DAS_RESULT status,
            int waitId,
            const Json::Value &result);

    virtual TransportInterface* TransportHandle(){return m_pTransport;}
private:
    int generateId(tJsonRpcInterface _interface, const std::string &method, int timeout);
    void deleteId(S32 msgId);
    bool findMethod(const std::string &method);
    void deleteMethod(const std::string &method);
private:
    LOG_MODULE_TRACE(ProtocolHandler);

    class RequestJson
    {
    public:
        RequestJson(int _index,
                const tJsonRpcInterface &_interface,
                const std::string &_method,
                int _timeout) {
            index = _index;
            interface = _interface;
            method = _method;
            time_start = time(NULL);
            timeout = _timeout;
        }

        ~RequestJson() {

        }

        bool IsTimeOut() {
            if (timeout == -1)
                return false;
            time_t now = time(NULL);

            return (now - time_start > timeout);
        }

        /*
         * 定时检测超时请求
         */
        bool handleJsonRpc(DAS_RESULT status,
                const Json::Value &result) {
            if (interface.valid()) {
                LOG_INFO("status = %d,method = %s",status,method.c_str());

                bool ret = interface->OnReceiveJson(index,status,method,result);
                if (status== DAS_SUCCESS && ret == false) {
                    timeout = -1;
                    return false;
                }
                return true;
            }
            else {
                LOG_INFO("delete:status = %d,method = %s",status,method.c_str());
                return true;
            }
        }
        int index;
        tJsonRpcInterface   interface;
        std::string         method;
//        Timer              *m_pTimer;
        time_t              time_start;
        int timeout;
    };

    Timer              *m_pTimer;
    U16                 m_uFlag;
    Lock                m_state_lock;

    S32          m_iMaxId;
    std::map<S32,RequestJson *> m_pRequestJson;
    struct WaitJson {
        WaitJson(S32 msgId_,
                 const std::string& method_,
                 DAS_RESULT ret_ = DAS_SUCCESS):
            msgId(msgId_),
            method(method_),
            ret (ret_) {

        }
        std::string method;
        S32 msgId;
        DAS_RESULT ret;
    };

    std::vector<WaitJson> m_vectorWaitJson;
    Lock                  m_wait_lock;
};

#endif//__PROTOCOLHANDLER_H__
